package com.yungu.swift.api.route.v1.passenger.pay.tenpay;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yungu.swift.api.base.BaseApi;
import com.yungu.swift.api.wxapi.WxConstants;
import com.yungu.swift.assets.passenger.model.dto.PassengerCouponDto;
import com.yungu.swift.assets.passenger.service.PassengerCouponService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.constants.OrderConstant;
import com.yungu.swift.constants.PassengerConstant;
import com.yungu.swift.order.model.vo.PayVo;
import com.yungu.swift.order.service.PayService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Zerrion
 */
@Controller
@Api(value = "【乘客】【支付】【微信】微信支付接口", tags = "微信支付的相关操作")
public class WxPayApi extends BaseApi {
    private final Logger logger = LoggerFactory.getLogger(WxPayApi.class);

    @Reference
    private PayService payService;
    @Reference
    private PassengerCouponService passengerCouponService;

    /**
     * 小程序支付
     *
     * @return
     */
    @RequestMapping(value = "/api/v1/passenger/token/wx/applet/tradeUrl", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "乘客微信小程序支付", response = ResponseData.class, notes = "乘客微信小程序支付接口")
    public ResponseData<Map<String, String>> wxAppletTradeUrl(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "orderUuid", value = "订单id", required = true) @RequestParam String orderUuid,
            @ApiParam(name = "couponUuid", value = "优惠券id") @RequestParam(required = false) String couponUuid,
            @ApiParam(name = "openid", value = "openid", required = false) @RequestParam(required = false) String openid,
            @ApiParam(name = "spbillCreateIp", value = "ip", required = true) @RequestParam String spbillCreateIp,
            HttpServletRequest request) {

        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        logger.info("+++++++++++++++++++++++++++++客户端Ip:" + ip + "+++++++++++++++++++++++++++++++++++++++");
        return payService.trade(new PayVo(OrderConstant.PAY_PURPOSE_CHARGE_FARE, CommonConstant.PASSENGER,
                OrderConstant.PAY_TYPE_TENPAY, getUserUid(request), orderUuid, couponUuid, null, WxConstants.APPID,
                ip, openid));
    }

    /**
     * 微信支付
     * 用户token
     *
     * @param request 请求
     * @return ResponseData
     * @throws Exception
     */
    @RequestMapping(value = "/api/v1/passenger/token/pay/wx/tradeUrl", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "乘客微信支付车费", response = ResponseData.class, notes = "乘客微信支付接口")
    public ResponseData<Map<String, String>> tradeUrl(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "orderUuid", value = "订单id", required = true) @RequestParam String orderUuid,
            @ApiParam(name = "couponUuid", value = "优惠券id") @RequestParam(required = false) String couponUuid,
            @ApiParam(name = "openid", value = "openid", required = false) @RequestParam(required = false) String openid,
            @ApiParam(name = "spbillCreateIp", value = "ip", required = true) @RequestParam String spbillCreateIp,
            HttpServletRequest request) {
        return payService.trade(new PayVo(OrderConstant.PAY_PURPOSE_CHARGE_FARE, CommonConstant.PASSENGER,
                OrderConstant.PAY_TYPE_TENPAY, getUserUid(request), orderUuid, couponUuid, null, appid,
                getUserIP(request), null));
    }

    /**
     * 解析微信发来的请求（XML）
     *
     * @param request
     * @return
     * @throws Exception
     */
    public static Map<String, String> parseXml(HttpServletRequest request)
            throws Exception {
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap(4);

        // 从request中取得输入流
        InputStream inputStream = request.getInputStream();
        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List<Element> elementList = root.elements();

        // 遍历所有子节点
        for (Element e : elementList) {
            map.put(e.getName(), e.getText());
        }
        // 释放资源
        inputStream.close();
        return map;
    }

    /**
     * 重置优惠券的状态
     *
     * @param couponId
     */
    private void resetCoupon(String couponId) {
        if (couponId != null) {
            PassengerCouponDto editStatus = new PassengerCouponDto();
            editStatus.setUuid(couponId);
            editStatus.setStatus(PassengerConstant.COUPON_STATUS_VALID);
            editStatus.setOrderUuid(null);
            editStatus.setUpdateBy("SYSTEM");
            editStatus.setUpdateOn(new Date());
            passengerCouponService.edit(editStatus);
        }
    }

    @ApiOperation(value = "乘客微信充值账户", notes = "返回成功或失败消息", response = ResponseData.class)
    @RequestMapping(value = {"/api/v1/passenger/token/wallet/walletWxPay"}, method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public ResponseData<Map<String, String>> walletWxPay(
            @ApiParam(name = "appid", value = "APP标识", required = true) @RequestParam String appid,
            @ApiParam(name = "rechargeId", value = "充值面额Id", required = true) @RequestParam String rechargeId,
            @ApiParam(name = "spbillCreateIp", value = "ip", required = true) @RequestParam String spbillCreateIp,
            @ApiParam(name = "openid", value = "openid", required = false) @RequestParam(required = false) String openid,
            HttpServletRequest request) {
        return payService.trade(new PayVo(OrderConstant.PAY_PURPOSE_RECHARGE_ACCOUNT, CommonConstant.PASSENGER,
                OrderConstant.PAY_TYPE_TENPAY, getUserUid(request), null, null, rechargeId, appid,
                spbillCreateIp, null));
    }

    @RequestMapping(value = "/wx/tradeUrl", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "乘客微信公众号支付车费", response = ResponseData.class, notes = "乘客微信公众号支付接口")
    public ResponseData<Map<String, String>> wxTradeUrl(
            @ApiParam(name = "orderUuid", value = "订单id", required = true) @RequestParam String orderUuid,
            @ApiParam(name = "couponUuid", value = "优惠券id") @RequestParam(required = false) String couponUuid,
            @ApiParam(name = "openid", value = "openid", required = false) @RequestParam(required = false) String openid,
            @ApiParam(name = "spbillCreateIp", value = "ip", required = true) @RequestParam String spbillCreateIp,
            HttpServletRequest request) {

        String passengerUuid = (String) request.getSession().getAttribute("passengerUuid");
        String userIP = getUserIP(request);
        return payService.trade(new PayVo(OrderConstant.PAY_PURPOSE_CHARGE_FARE, CommonConstant.PASSENGER,
                OrderConstant.PAY_TYPE_TENPAY, StringUtils.trimToEmpty(passengerUuid), orderUuid, couponUuid,
                null, WxConstants.APPID, userIP, openid));
    }

    @RequestMapping(value = "/wx/token/h5TradeUrl", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    @ApiOperation(value = "乘客H5微信支付", response = ResponseData.class, notes = "乘客H5微信支付接口")
    public ResponseData<Map<String, String>> h5TradeUrl(
            @ApiParam(name = "orderUuid", value = "订单id", required = true) @RequestParam String orderUuid,
            @ApiParam(name = "couponUuid", value = "优惠券id") @RequestParam(required = false) String couponUuid,
            HttpServletRequest request) {
        return payService.trade(new PayVo(OrderConstant.PAY_PURPOSE_CHARGE_FARE, CommonConstant.PASSENGER,
                OrderConstant.PAY_TYPE_TENPAY, getUserUid(request), orderUuid, couponUuid, null,
                WxConstants.APPID, getUserIP(request), null));
    }
}
